package com.tlgen.orm.components.rest;

import com.google.common.collect.Maps;
import com.tlgen.orm.components.sqlXml.SQLXMLMethod;
import com.tlgen.orm.components.sqlXml.SqlExecutor;
import com.tlgen.orm.param.FieldParam;
import com.tlgen.orm.utils.ClassesUtils;
import com.tlgen.orm.utils.xml.SqlXmlLoader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import static com.tlgen.orm.utils.ClassesUtils.matchesSQLXMLMethod;

@Slf4j
public class RestProxy<T> implements InvocationHandler, Serializable {

    Class<T> restInterface;

    public RestProxy(Class<T> restInterface) {
        this.restInterface = restInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        return executeRestFul(proxy, method, args);
    }

    private Object executeRestFul(Object proxy, Method method, Object[] args) {
        try {
            // 获取需要执行 SQL-XML 的方法
            List<SQLXMLMethod> methods = ClassesUtils.getSQLXMLMethod();
            if (CollectionUtils.isEmpty(methods) || !matchesSQLXMLMethod(method.getName(), methods)) {
                // 走默认具体实现类实现
                return method.invoke(proxy, args);
            }
            // 提取参数
            List<FieldParam> params = ParamExtractor.extractParams(method, args);
            Map<String, Object> paramMap = Maps.newHashMap();
            for (FieldParam param : params) {
                paramMap.put(param.getName(), param.getValue());
            }
            // 执行 SQL
            String SQL = SqlXmlLoader.parserQLXMLByMethodName(method.getName(), paramMap);
            Class<?> returnType = method.getGenericReturnType().getClass();
            return SqlExecutor.create().executeSql(SQL, paramMap, returnType);
        } catch (Exception e) {
            log.error("RestProxy error:", e);
            throw new RuntimeException(e);
        }
    }

}
